#include "constantes.h"
#include "semaforos.h"

int main(int argc, char *argv[])
{
	char mensaje[150];					/* Mensaje para imprimir por pantalla */
	int childpid;

	if ( argc != 6 )					/* Nombre de ejecutable + 3 variables */
	{
		sprintf(mensaje, "%s Uso: <cant clientes> <cant encargados> <cant ayudantes> <cant panaderos> <cant parrilleros>\n", argv[0]);
		write(fileno(stdout), mensaje, strlen(mensaje));

		exit(0);
	}

        int nroprogramas = argc - 2;                            /* Numero de programas que voy a ejecutar (comienza en 0) */
        int cantprocesos[nroprogramas];                         /* Cantidad de procesos que levanto por programa */
        char *nombreprograma[nroprogramas];                     /* Nombre de los binarios que ejecutare */

                                                              /* Se ingresan las cantidades por parametro */
        cantprocesos[0] = atoi(argv[1]);                      /* Cantidad de Procesos Cliente */
        cantprocesos[1] = atoi(argv[2]);                      /* Cantidad de Procesos Encargados */
        cantprocesos[2] = atoi(argv[3]);                      /* Cantidad de Procesos Ayudantes */
        cantprocesos[3] = atoi(argv[4]);                      /* Cantidad de Procesos Panaderos */
        cantprocesos[4] = atoi(argv[5]);                      /* Cantidad de Procesos Parrilleros */

	/* Hago algunas manganetas con el PATH para no depender de las rutas */
	char *pathenv;						/* de los archivos para poder ejecutarlos */
	int pathsize = 2 * sizeof(pathenv);
	char newpathenv[pathsize];
	pathenv = (char *)getenv("PATH");			/* Obtengo el valor de la variable de enviroment PATH */
	strcpy(newpathenv, pathenv);
	strcat(newpathenv, ":.");				/* Agrego el directorio donde estoy parado, se puede poner otro... */
	setenv("PATH", newpathenv, 1);

	/* Defino los nombres de los binarios que voy a ejecutar */
	nombreprograma[0] = "cliente";
	nombreprograma[1] = "encargado";
	nombreprograma[2] = "ayudante";
	nombreprograma[3] = "panadero";
	nombreprograma[4] = "parrillero";

	/* Antes de arrancar los procesos creo las colas, memorias compartidas y semaforos */
	int cola_cli_enc;					/* Cola Cliente-Encargado (en lugar de TCP) */
	int cola_enc_ayu;					/* Cola Encargado-Ayudante */
	key_t clave_cli_enc;
	key_t clave_enc_ayu;

	/*
	 * Colas
	 * 1- Para el Cliente-Encargado
	 * 2- Para el Encargado-Ayudante
	 */
	clave_cli_enc = ftok(DIRECTORIO, COLA_CL_ENC);
	if( (cola_cli_enc = msgget(clave_cli_enc, IPC_CREAT|0666)) < 0 )
	{
                sprintf(mensaje, "Error al crear la cola Cliente-Encargado\n");
                write(fileno(stdout), mensaje, strlen(mensaje));

                exit(-1);
	}
	
	/* Usamos 1 sola 
	clave_enc_ayu = ftok(DIRECTORIO, COLA_ENC_AYU);
	if( (cola_enc_ayu = msgget(clave_enc_ayu, IPC_CREAT|0666)) < 0 )
	{
                sprintf(mensaje, "Error al crear la cola Encargado-Ayudante\n");
                write(fileno(stdout), mensaje, strlen(mensaje));

                exit(-1);
	}
	*/

	int shmid_parrilla;
	int shmid_tabla;
	key_t clave_parrilla;
	key_t clave_tabla;
	
	/*
	 * Shared Memory
	 * 1- Para la parrilla (el parrillero y ayudante la utilizan)
	 * 2- Para la tabla (el panadero y ayudante la utilizan)
	 */
	clave_parrilla = ftok(DIRECTORIO, SHM_PARRILLA);
	if( (shmid_parrilla = shmget(clave_parrilla, sizeof(t_parrilla), IPC_CREAT | 0660)) < 0 )
	{
                sprintf(mensaje, "Error al crear la Shared Memory Parrilla\n");
                write(fileno(stdout), mensaje, strlen(mensaje));

		exit(-1);
	}

	clave_tabla = ftok(DIRECTORIO, SHM_TABLA);
	if( (shmid_tabla = shmget(clave_tabla, sizeof(t_tabla), IPC_CREAT | 0660)) < 0 )
	{
                sprintf(mensaje, "Error al crear la Shared Memory Tabla\n");
                write(fileno(stdout), mensaje, strlen(mensaje));

		exit(-1);
	}

	/*
	 * Semaforos
	 */
	int semid_parrilla;
	int semid_hacerchori;
	int semid_tabla;
	int semid_hacerpan;

	if ( (semid_parrilla = creasem(SEM_PARRILLA)) < 0 )
	{
                sprintf(mensaje, "Error al crear el semaforo Parrilla\n");
                write(fileno(stdout), mensaje, strlen(mensaje));

		exit(-1);
	}

	/* Inicializo el semaforo como libre = TRUE */
	if ( inisem(semid_parrilla, TRUE) < 0 )
	{
                sprintf(mensaje, "Error al inicializar el semaforo Parrilla\n");
                write(fileno(stdout), mensaje, strlen(mensaje));

		exit(-1);
	}

	int nollenoc = creasem(SEM_NOLLENOC);
	inisem(nollenoc, TRUE);
	int novacioc = creasem(SEM_NOVACIOC);
	inisem(novacioc, TRUE);

	if ( (semid_tabla = creasem(SEM_TABLA)) < 0 )
	{
                sprintf(mensaje, "Error al crear el semaforo Tabla\n");
                write(fileno(stdout), mensaje, strlen(mensaje));

		exit(-1);
	}

	/* Inicializo el semaforo como libre = TRUE */
	if ( inisem(semid_tabla, TRUE) < 0 )
	{
                sprintf(mensaje, "Error al inicializar el semaforo Tabla\n");
                write(fileno(stdout), mensaje, strlen(mensaje));

		exit(-1);
	}

	semid_hacerpan = creasem(SEM_HACERPAN);
	inisem(semid_hacerpan, TRUE);

/*
	printf("Ya quedo todo inicializado\n");

	/ * Levanto los procesos (Maria decia de no usar variables del programa despues del fork, pero ...) * / 
	int programa;
	int proceso;
	int parametro = 0;

	for ( programa=0; programa <= nroprogramas; programa++ )
	{
		for ( proceso=0; proceso < cantprocesos[programa]; proceso++ )
		{
			if ((childpid = fork()) < 0)
			{
				perror("Error en el fork");
				exit(1);
			}
			else if (childpid == 0)
			{
				sprintf(mensaje, "Iniciando %s Nro. %d\n", nombreprograma[programa], proceso + 1);
				write(fileno(stdout), mensaje, strlen(mensaje));

				if (execlp(nombreprograma[programa], nombreprograma[programa], parametro, (char *)0) != 0){
					perror("Error en execlp");
					exit(1);
				}
			}
		}
	}

*/
 return 0;
}
